#include "labelListmodel.h"
#include "session.h"
#include "graph.h"
#include <algorithm>
#include <QtGui/QtGui>
LabelListModel::LabelListModel(QObject * s, Graph g) : QAbstractItemModel{ s }, graph{ g } 
{

}

QVariant LabelListModel::data(const QModelIndex& index, int role) const {
	if (!index.isValid())
		return QVariant();
	switch (index.column()) {
	case 0:
	{
		Point n = m_markPoints[index.row()];
		switch (role) {
		case Qt::DisplayRole:
			return index.row();
		case Qt::DecorationRole:
			return QIcon{ n.m ? ":/images/breeze/dialog-ok.svg" : ":/images/breeze/emblem-important.svg" };
		}
	}
	break;
	case 1:
	{
		Point n = m_markPoints[index.row()];
		
		switch (role) {
		case Qt::DisplayRole:
			return QString::number(n.m);
		case Qt::EditRole:
			return QString::number(n.m);
		}
	}
	break;
	}
	return QVariant();
}
int LabelListModel::columnCount(const QModelIndex& parent) const {
	return 2;
}
Qt::ItemFlags LabelListModel::flags(const QModelIndex& index) const {
	if (!index.isValid())
		return 0;
	if (index.column() == 1)
		return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
	return QAbstractItemModel::flags(index);
}

bool LabelListModel::hasChildren(const QModelIndex& parent) const {
	if (!parent.isValid())
		return graph.trees().size()>0;
	return false;
}

QVariant LabelListModel::headerData(int section, Qt::Orientation orientation, int role) const {
	if (role != Qt::DisplayRole)
		return QVariant();
	switch (section) {
	case 0:
		return QString("Index");
	case 1:
		return QString("Mark");
	}
	return QVariant();
}

QModelIndex LabelListModel::index(int row, int column, const QModelIndex& parent) const {
	if (parent.isValid()) {
		return QModelIndex();
	}
	else {
		if (row >= 0 && static_cast<size_t>(row)<m_markPoints.size() && column<columnCount()) {
			return createIndex(row, column);
		}
		else {
			return QModelIndex();
		}
	}
}

int LabelListModel::rowCount(const QModelIndex& parent) const {

	return m_markPoints.size();
}

QModelIndex LabelListModel::parent(const QModelIndex& index) const {
	return QModelIndex();
}

bool LabelListModel::setData(const QModelIndex& index, const QVariant& value, int role) {

	return false;
}

void LabelListModel::update(Point& p)
{
	if (p.m < 0) {
		clear();
		auto edges = graph.edges();
		for (auto edge : edges) {
			if (edge.tree() && edge.tree().selected()) {
				for (auto &point : edge.points()) {
					switch (point.m)
					{
					case 1:
					case 2:
					case 3:
					{
						auto it = std::find(m_markPoints.begin(), m_markPoints.end(), point);
						if (it == m_markPoints.end()) {
							beginInsertRow(rowCount());
							m_markPoints.push_back(point);
							endInsertRow();
						}
						break;
					}

					}
				}
			}
		}
	}
	else {
		auto it = std::find(m_markPoints.begin(), m_markPoints.end(), p);
		if (it != m_markPoints.end()) {
			int index = std::distance(m_markPoints.begin(), it);
			switch (p.m)
			{
			case 0:
				//remove
				beginRemoveRow(index);
				m_markPoints.erase(it);
				endRemoveRow();
				break;
			default:
				//update
				
				m_markPoints[index] = p;
				emit dataChanged(QModelIndex(), QModelIndex());
				break;
			}
		}
		else {
			switch (p.m)
			{
			case 0:
				break;
			default:
				//insert
				beginInsertRow(rowCount());
				m_markPoints.push_back(p);
				endInsertRow();
				break;
			}
		}
	}
}

void LabelListModel::clear()
{
	int count = rowCount();
	if (count) {
		beginRemoveRows(QModelIndex(), 0, count - 1);
		endRemoveRows();
		m_markPoints.clear();
	}
}

